//XMLRequest()
//.get()
//.getResponceText()

//Utils.isDefined()
//CoreIMSEEException


ClassLoader.prototype.load=function (className){
    //For now, script may be emitted only during a load. This means you must
    //call using() only before whole page is loaded. May be some more complex
    //mechanism will be provided.  
    if (document.loaded) throw new CoreIMSEEException("Classes may be loaded only during page load.");
	
	try {
	    if (typeof(eval(className))=="function") return;
	} catch (e) {}
	
	if (this.isLoaded(className)){
		return;
	}
	//We should mark class as loaded before loading to prevent cycle references
    this.loadedClasses.push(className);
    var request = new XMLRequest(this.getFileName(className));
    request.get(null, false);
    this.emitScript(request.getResponceText());        
}

ClassLoader.prototype.emitScript = function(text){
    document.write("<script>"+text+"\<\/script>");
}

ClassLoader.prototype.getFileName = function(className){
	var classFile;
	if (this.classes!=null&&this.classes[className]!=null){
	    classFile = this.classes[className].fileName;    
	}
	if (!Utils.isDefined(classFile)){
	    classFile = className + ".js"; 
	}
	
	/*if (!Utils.isDefined(classFile)){
		throw new CoreIMSEEException(String.format("Cannot locate class \"{0}\".", className));  
	}*/
	
  
    return (this.scriptBase.endsWith("/")?this.scriptBase:this.scriptBase+"/")+classFile;
}

ClassLoader.prototype.batchLoad=function (classNames){
	for (var i=0; i<classNames.length; i++){
		this.load(classNames[i]);
	}
}

ClassLoader.prototype.isLoaded=function (className){	
	for (var i=0; i<this.loadedClasses.length; i++) {
	    if (this.loadedClasses[i]==className) return true;
	}
	
	return false;
}

//Inmplements prototype inheritance
ClassLoader.prototype.inherit = function (childClassName, parentClassName) {
    childClass = eval(childClassName);
    parentClass = eval(parentClassName);
	for (var m in parentClass.prototype) { 
	    childClass.prototype[m] = parentClass.prototype[m]; 
	} 
	childClass.prototype[parentClassName] = parentClass;
}

ClassLoader.instance=null;

function ClassLoader(scriptBase, classes, loadedClasses){
	this.scriptBase=scriptBase;
	this.classes=classes;
	this.loadedClasses=loadedClasses;
}

ClassLoader.create=function (scriptBase, classes, loadedClasses){
	ClassLoader.instance=new ClassLoader(scriptBase, classes, loadedClasses);
	
}

//Convenience methods

Function.prototype.inherit = function (parentClassName){
    ClassLoader.instance.inherit(this.getName(), parentClassName);
}

function using(className){
	ClassLoader.instance.load(className);
}

